/*
 *  levelUpGame - InputController.cpp
 *  Copyright 2011 W. Reckman. All rights reserved.
 */
#include "Utils.h"
#include "InputController.h"


InputController::InputController()
: s( Settings::getInstance() ), deviceId( -1 ), baudRate ( -1 )
{}


void InputController::setup() {
	 
	/* add player bindings */
	
	PlayerBindings pb;
	
	//player 1
	pb.emulationEnabled = false; pb.keyUp = OF_KEY_UP; pb.keyDown = OF_KEY_DOWN;
	pb.keyLeft = OF_KEY_LEFT; pb.keyRight = OF_KEY_RIGHT; pb.keyStop = ' ';
	playerBindings.push_back( pb );
	
	//player 2
	pb.emulationEnabled = false; pb.keyUp = 'w'; pb.keyDown = 's';
	pb.keyLeft = 'a'; pb.keyRight = 'd'; pb.keyStop = 'x';
	playerBindings.push_back( pb );
	
	
	/* init serial if enabled or enable emulation otherwise */
	
	serialEnabled = parseBool( *s.getValueInGroup( "serial_enabled", "settings", "true" ) );
	
	if ( serialEnabled ) {
		deviceId = ofToInt( *s.getValueInGroup( "serial_device_id", "settings", "-1" ) );
		baudRate = ofToInt( *s.getValueInGroup( "serial_baudrate", "settings", "-1" ) );
		
		if ( deviceId == -1 ) {
			ofLog( OF_LOG_ERROR, "(InputController.cpp) could not initialize serial device, config key 'serial_device_id' does not exist" );
			return;
		}
		
		if ( baudRate == -1 ) {
			ofLog( OF_LOG_ERROR, "(InputController.cpp) could not initialize serial device, config key 'serial_baudrate' does not exist" );
			return;
		}
		
		serialJoystick.setup( deviceId, baudRate );
		ofAddListener( serialJoystick.onJoystickMoved, this, &InputController::onJoystickMoved );
	} else {
		ofLog( OF_LOG_NOTICE, "(InputController.cpp) serial port not enabled" );
		
		for ( int i = 0; i < playerBindings.size(); ++i ) {
			playerBindings[i].emulationEnabled = true;
		}
	}
}

void InputController::update() {
	if ( serialEnabled ) serialJoystick.update();
}

void InputController::keyPressed( int key ) {
	EventArgsJoystick ev;
	
	for ( int i = 0; i < playerBindings.size(); ++i ) {
		const PlayerBindings& pb = playerBindings[i];
		if ( pb.emulationEnabled ) {
			bool foundKey = false;
			
			ev.joystickNum = i;
			
			if ( key == pb.keyUp ) {
				ev.joystickDirection = EventArgsJoystick::DIRECTION_UP;
				foundKey = true;
			} else if ( key == pb.keyDown ) {
				ev.joystickDirection = EventArgsJoystick::DIRECTION_DOWN;
				foundKey = true;
			} else if ( key == pb.keyLeft ) {
				ev.joystickDirection = EventArgsJoystick::DIRECTION_LEFT;
				foundKey = true;
			} else if ( key == pb.keyRight ) {
				ev.joystickDirection = EventArgsJoystick::DIRECTION_RIGHT;
				foundKey = true;
			} else if ( key == pb.keyStop ) {
				ev.joystickDirection = EventArgsJoystick::DIRECTION_STOP;
				foundKey = true;
			}
			
			if ( foundKey ) {
				if ( ev.joystickDirection != EventArgsJoystick::DIRECTION_STOP ) {
					ev.joystickPinNum = (int)ev.joystickDirection;
					ev.joystickStatus = true;
				} else {
					ev.joystickPinNum = 0;
					ev.joystickStatus = false;
				}
				
				ofNotifyEvent( onPlayerInput, ev, this );
				break;
			}
		}
	}
	
	//--debug serial
	if ( key == '@' ) {
		ofLog( OF_LOG_NOTICE, "---RESTART SERIAL CONNECTION---", deviceId, baudRate );
		serialJoystick.close();
		serialJoystick.setup( deviceId, baudRate );
	}
}

/*********************
 * PRIVATE FUNCTIONS *
 *********************/
/*******************
 * EVENT CALLBACKS *
 *******************/

void InputController::onJoystickMoved( EventArgsJoystick& ev_ ) {
	if ( serialEnabled ) {
		int playerId = ev_.joystickNum;
		if ( playerBindings.size() <= playerId || ! playerBindings[playerId].emulationEnabled ) {
			ofNotifyEvent( onPlayerInput, ev_, this );
		}
	}
}
